const THREE = require('three');
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
//  创建时钟对象，用于计算FPS
const clock = new THREE.Clock();
const scene = new THREE.Scene();
const threeRender = new THREE.WebGLRenderer();
const myThree = {
    scene, // 场景实例
    threeRender, // 渲染实例
    camera: null, //相机实例
    controls: null, //相机控制对象
    stop: false, //渲染停止变量，设置为true 则停止渲染，停止后自动恢复至false，若需要开启渲染重新调用reDraw
    reDraw: back => {
        // 获取两次执行时间间隔，单位s
        const time = clock.getDelta();
        let FPS = Math.floor(1 / time);
        back(FPS);
        !myThree.stop &&
            requestAnimationFrame(() => {
                myThree.reDraw(FPS => {
                    back(FPS);
                });
            });
        myThree.stop = false;
    },
    // 创建网格模型
    CreatMesh: (geometric, skin) => {
        let mesh = new THREE.Mesh(geometric, skin);
        myThree.scene.add(mesh);
        return mesh;
    },
    // 渲染场景，仅支持myThree内相机
    SetRender: id => {
        let box = document.querySelector(`#${id}`);
        myThree.threeRender.setSize(box.offsetWidth, box.offsetHeight);
        myThree.threeRender.render(myThree.scene, myThree.camera);
        box.appendChild(myThree.threeRender.domElement);
    },
    // 开启轨道控制器
    OpenCameraControl: ({ x = 400, y = 400, z = 400 }, { x1 = 400, y1 = 400, z1 = 400 }) => {
        myThree.controls = new OrbitControls(myThree.camera, myThree.threeRender.domElement);
        // 修改相机控制按键
        // https://blog.csdn.net/qq_41960265/article/details/109238386
        myThree.controls.mouseButtons = {
            // LEFT: THREE.MOUSE.PAN, //平移
            LEFT: null,
            MIDDLE: THREE.MOUSE.DOLLY, //缩放
            RIGHT: THREE.MOUSE.ROTATE, //旋转
        };
        // 修改相机位置
        myThree.camera.position.set(x, y, z);
        // 修改相机朝向
        myThree.controls.target = new THREE.Vector3(x1, y1, z1);
        // 相机更新
        myThree.controls.update();
    },
    // 监听dom点击事件
    CanvasDomClick: (id, back) => {
        let box = document.querySelector(`#${id}`);
        myThree.threeRender.domElement.addEventListener('click', event => {
            let { offsetX, offsetY } = event;
            const x = (offsetX / box.offsetWidth) * 2 - 1;
            const y = 1 - (offsetY / box.offsetHeight) * 2;
            const mousePoint = new THREE.Vector2(x, y);
            let raycaster = new THREE.Raycaster();
            raycaster.setFromCamera(mousePoint, myThree.camera);
            const eventObject = raycaster.intersectObjects(myThree.scene.children);
            back(eventObject, event);
        });
    },
    CreatCamera: (deg, randomId, near = 1, far = 12000) => {
        // （透视投影）{拍摄角度,长宽比，近点默认为0，远点默认12000}
        let box = document.querySelector(`#${randomId}`);
        myThree.camera = new THREE.PerspectiveCamera(deg, box.offsetWidth / box.offsetHeight, near, far);
        return myThree.camera;
    },
    CameraPosition: (object, { x, y, z, x1 = 290, y1 = 290, z1 = 290 }) => {
        object.position.set(x, y, z);
        object.lookAt(x1, y1, z1);
    },
};
export { myThree };
export default THREE;

// 1、reDraw 使用示例
/**
 * @params timer 定时器标识
 */
// this.$myThree.reDraw(fps => {
//     this.timer
//         ? true
//         : (this.timer = setTimeout(() => {
//               this.timer = null;
//               this.fps = fps;
//           }, 500));
// });

// 2、如何停止
// this.$myThree.stop = true; 即可，渲染停止后，stop属性自动设置为false
